package Concurrency2.Chapter02_InnerLockPrinciple;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;

import static utils.MUtils.*;

/**
 * Instruction：生产者消费者模型 - 分离变化与不变
 * 变化: 数据缓冲容器
 * 不变: 生产者消费者
 * Author：@author MaLi
 */
public class T03_ProducerConsumer {

    public static void main(String[] args) {

        //创建生产者动作
        //创建消费者动作

        //批量创建生产者, 消费者
    }

    //组件一: 数据缓冲容器
    private static class DataContainer<T>{
        //最大容量
        private static final int MAX_AMOUNT = 10;
        //容器
        private List<T> container = new LinkedList<>();
        //当前容量
        private AtomicInteger amount = new AtomicInteger(0); //对当前容量计数?

        //添加元素
        public void add(T element) {
            if (amount.get()>=MAX_AMOUNT) {
                print("队列已满");
                return;
            }
            container.add(element);
            amount.incrementAndGet();
            print("Container add"+element);
        }

        //移除元素
        public T get() {
            if (amount.get()<=0) {
                print("队列已空");
                return null;
            }
            T element = container.remove(0);
            amount.decrementAndGet();
            return element;
        }
    }

    //组件二: 生产者
    private static class Producer implements Runnable {
        private static AtomicInteger TURN = new AtomicInteger(1); //用于记录所有生产者产出总次数
        private static AtomicInteger PRODUCER_NO = new AtomicInteger(1);
        private String producerName; //生产者Name
        private Callable action;//解耦生产者逻辑

        public Producer(Callable action) {
            this.action = action;
            this.producerName = "Producer" + PRODUCER_NO.getAndIncrement();
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Object result = action.call();
                    if (null != result) {
                        String msg = "Producer: " + producerName + " --> 第" + TURN.getAndIncrement() + "轮 --> 产出:" + result;
                        print(msg);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    //组件三: 消费者
    private static class Consumer implements Runnable{
        private static AtomicInteger TURN = new AtomicInteger(1); //用于记录所有生产者产出总次数
        private static AtomicInteger CONSUMER_NO = new AtomicInteger(1);
        private String consumerName; //生产者Name
        private Callable action;//解耦生产者逻辑

        public Consumer(Callable action) {
            this.action = action;
            this.consumerName = "Consumer" + CONSUMER_NO.getAndIncrement();
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Object result = action.call();
                    if (null != result) {
                        String msg = "Consumer: " + consumerName + " --> 第" + TURN.getAndIncrement() + "轮 --> 消费:" + result;
                        print(msg);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
